package Server.Poker.ZJH;

import java.io.Serializable;
import java.util.Random;



public class GameLogic implements Serializable {

	public static int DRAW = 2; // 和局类型

	// 数值掩码
	public static int LOGIC_MASK_COLOR = (int) 0xF0; // 花色掩码
	public static int LOGIC_MASK_VALUE = 0x0F; // 数值掩码


	public	int[]	m_byPokerPai;

	public GameLogic()
	{
		m_byPokerPai = new int[52];
	}
	int random(int iMin, int iMax){
		Random ra =new Random();
		return ra.nextInt(iMax-iMin) + iMin;
	}	
	int m_cbCardListData[] = {
			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,	//方块 A - K
			0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,	//梅花 A - K
			0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,	//红桃 A - K
			0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D,	//黑桃 A - K
			 };
	

	public static void Test()
	{
		GameLogic m_GameLogic = new GameLogic();
		int cardArray[] = new int[5 * 3];
		m_GameLogic.RandCardList(cardArray, 5 * 3);
		int out_data[] = new int[5];
		m_GameLogic.AnKongCard(cardArray, cardArray,5,3);
	}
	//获取类型
	public int GetCardType(int cbCardData[], int cbCardCount)
	{

		if (cbCardCount == 3)
		{
			//变量定义
			boolean cbSameColor = true, bLineCard = true;
			int cbFirstColor = GetCardColor(cbCardData[0]);
			int cbFirstValue = GetCardLogicValue(cbCardData[0]);

			//牌形分析
			for (int i = 1; i < cbCardCount; i++)
			{
				//数据分析
				if (GetCardColor(cbCardData[i]) != cbFirstColor) cbSameColor = false;
				if (cbFirstValue != (GetCardLogicValue(cbCardData[i]) + i)) bLineCard = false;

				//结束判断
				if ((cbSameColor == false)&&(bLineCard == false)) break;
			}

			//特殊A32
			if (!bLineCard)
			{
				boolean bOne = false, bTwo = false, bThree = false;
				for (int i = 0; i < 3; i++)
				{
					if (GetCardValue(cbCardData[i]) == 1)		bOne = true;
					else if (GetCardValue(cbCardData[i]) == 2)	bTwo = true;
					else if (GetCardValue(cbCardData[i]) == 3)	bThree = true;
				}
				if (bOne && bTwo && bThree)bLineCard = true;
			}

			//顺金类型
			if ((cbSameColor)&&(bLineCard)) return Constants.CT_SHUN_JIN;

			//顺子类型
			if ((!cbSameColor)&&(bLineCard)) return Constants.CT_SHUN_ZI;

			//金花类型
			if ((cbSameColor)&&(!bLineCard)) return Constants.CT_JIN_HUA;

			//牌形分析
			boolean bDouble = false, bPanther = true;

			//对牌分析
			for (int i = 0; i < cbCardCount - 1; i++)
			{
				for (int j = i + 1; j < cbCardCount; j++)
				{
					if (GetCardLogicValue(cbCardData[i]) == GetCardLogicValue(cbCardData[j])) 
					{
						bDouble = true;
						break;
					}
				}
				if (bDouble)break;
			}

			//三条(豹子)分析
			for (int i = 1; i < cbCardCount; i++)
			{
				if (bPanther && cbFirstValue != GetCardLogicValue(cbCardData[i])) bPanther = false;
			}

			//对子和豹子判断
			if (bDouble == true) return (bPanther) ? Constants.CT_BAO_ZI : Constants.CT_DOUBLE;

			//特殊235
			boolean bTwo = false, bThree = false, bFive = false;
			for (int i = 0; i < cbCardCount; i++)
			{
				if (GetCardValue(cbCardData[i]) == 2)	bTwo = true;
				else if (GetCardValue(cbCardData[i]) == 3)bThree = true;
				else if (GetCardValue(cbCardData[i]) == 5)bFive = true;			
			}	
			if (bTwo && bThree && bFive) return Constants.CT_SPECIAL;
		}

		return Constants.CT_SINGLE;
	}
	//获取数值
	int GetCardValue(int cbCardData) { return (int) (cbCardData&LOGIC_MASK_VALUE); }
	//获取花色
	int GetCardColor(int cbCardData) { return (int) (cbCardData&LOGIC_MASK_COLOR); }
	//排列扑克
	void SortCardList(int cbCardData[], int cbCardCount)
	{
		//转换数值
		int[] cbLogicValue = new int[3];
		for (int i = 0; i < cbCardCount; i++) cbLogicValue[i] = GetCardLogicValue(cbCardData[i]);	

		//排序操作
		boolean bSorted = true;
		int cbTempData, bLast = (int) (cbCardCount - 1);
		do
		{
			bSorted = true;
			for (int i = 0; i < bLast; i++)
			{
				if ((cbLogicValue[i] < cbLogicValue[i + 1]) ||
					((cbLogicValue[i] == cbLogicValue[i + 1])&&(cbCardData[i] < cbCardData[i + 1])))
				{
					//交换位置
					cbTempData = cbCardData[i];
					cbCardData[i] = cbCardData[i + 1];
					cbCardData[i + 1] = cbTempData;
					cbTempData = cbLogicValue[i];
					cbLogicValue[i] = cbLogicValue[i + 1];
					cbLogicValue[i + 1] = cbTempData;
					bSorted = false;
				}	
			}
			bLast--;
		} while (bSorted == false);

		return;
	}

	//剩余的牌的个数
	int GetYuPaiCount(int byPoker)
	{
		int total = 0;
		for (int i = 0;i<52;i++)
		{
			if(m_byPokerPai[i] == byPoker)
			{
				total++;
			}
			if (total > 1)
			{
				return 0;
			}
		}
		return total;
	}
	void AnKongCard(int out_cbCardData[],int in_cbCardData[],int cbUserCount, int cbCardCount)
	{
		int cbMaxCardType = 0;
		Random r0 = new Random();
		
		int max_card_seat = -1;
		
		for(int i = 0;i < cbUserCount;i++)
		{
			if(in_cbCardData[i*cbCardCount + 0] > 0)
			{
				int tmp_card[] = new int[cbCardCount];
				for(int k = 0;k < cbCardCount;k++)
				{
					tmp_card[k] = in_cbCardData[i*cbCardCount + k];
				}
				int cbTmpCardType = GetCardType(tmp_card,cbCardCount);
				
				if(cbTmpCardType > cbMaxCardType)
				{
					cbMaxCardType = cbTmpCardType;
					max_card_seat = i;
				}
			}
		}

		if(max_card_seat >= 0)
		{
			GetDaPai(out_cbCardData,cbMaxCardType,in_cbCardData[max_card_seat*cbCardCount]);
			System.out.printf("AN KONG (%d,%d,%d)\n",out_cbCardData[0],out_cbCardData[1],out_cbCardData[2]);
		}			
	}
	void GetDaPai(int out_cbCardData[],int cbSrcCardType,int minCard)
	{
		int color_start_rand = random(0,5000);
		if(cbSrcCardType <= Constants.CT_SHUN_ZI)
		{	
			int[][] vecColor = {{0,1,2},{0,1,3},{0,2,3},{1,2,3},{2,1,3},{2,3,1},{3,2,1},{3,2,0},{3,1,0},{3,1,2}};

			for(int c=0;c<10;c++)
			{
				int color1 = (color_start_rand % 10 + c) % 10;
				for(int i = 0;i < 11;i++)
				{
					if(m_byPokerPai[vecColor[color1][0] * 13 + i] > 0 && m_byPokerPai[vecColor[color1][1] * 13 + i+1] > 0 && m_byPokerPai[vecColor[color1][2] * 13 + i+2] > 0)
					{						
						if(cbSrcCardType == Constants.CT_SHUN_ZI)
						{
							if(m_byPokerPai[vecColor[color1][0] * 13 + i] % 13 > minCard % 13)
							{
								out_cbCardData[0] = m_byPokerPai[vecColor[color1][0] * 13 + i];
								out_cbCardData[1] = m_byPokerPai[vecColor[color1][1] * 13 + i+1];
								out_cbCardData[2] = m_byPokerPai[vecColor[color1][2] * 13 + i+2];
								m_byPokerPai[vecColor[color1][0] * 13 + i] = 0;
								m_byPokerPai[vecColor[color1][1] * 13 + i+1] = 0;
								m_byPokerPai[vecColor[color1][2] * 13 + i+2] = 0;
								return;
							}
						}else
						{
							out_cbCardData[0] = m_byPokerPai[vecColor[color1][0] * 13 + i];
							out_cbCardData[1] = m_byPokerPai[vecColor[color1][1] * 13 + i+1];
							out_cbCardData[2] = m_byPokerPai[vecColor[color1][2] * 13 + i+2];
							m_byPokerPai[vecColor[color1][0] * 13 + i] = 0;
							m_byPokerPai[vecColor[color1][1] * 13 + i+1] = 0;
							m_byPokerPai[vecColor[color1][2] * 13 + i+2] = 0;
							return;
						}
					}
				}
			}
		}
		if(cbSrcCardType <= Constants.CT_JIN_HUA)
		{			
			for(int c =0;c<4;c++)
			{
				int color1 = (color_start_rand % 4 + c) % 4;
				int cntPoker = 0;
				for(int i = 0;i < 13;i++)
				{			
					if(m_byPokerPai[color1 * 13 + i] > 0)
					{
						cntPoker++;
					}
				}
				if (cntPoker >= 3) {
					int out_index = 0;

					if (cbSrcCardType == Constants.CT_JIN_HUA) {
						for (int i = 12; i >=0; i--) {
							if (m_byPokerPai[color1 * 13 + i] > 0) {
								out_cbCardData[out_index] = m_byPokerPai[color1 * 13 + i];
								m_byPokerPai[color1 * 13 + i] = 0;
								out_index++;
								if (out_index >= 3) {
									SortCardList(out_cbCardData, 3);
									return;
								}
							}
						}
					} else {
						for (int i = 0; i < 13; i++) {
							if (m_byPokerPai[color1 * 13 + i] > 0) {
								out_cbCardData[out_index] = m_byPokerPai[color1 * 13 + i];
								m_byPokerPai[color1 * 13 + i] = 0;
								out_index++;
								if (out_index >= 3) {
									SortCardList(out_cbCardData, 3);
									return;
								}
							}
						}
					}
				}
			}
		}

		//不出金花就出豹子	
		if(cbSrcCardType == Constants.CT_BAO_ZI || cbSrcCardType == Constants.CT_SHUN_JIN)
		{
			int[][] vecColor = {{0,1,2},{0,1,3},{0,2,3},{1,2,3}};

			for(int c=0;c<4;c++)
			{
				int color1 = (color_start_rand % 4 + c) % 4;
				for(int i = 0;i < 13;i++)
				{
					if(m_byPokerPai[vecColor[color1][0] * 13 + i] > 0 && m_byPokerPai[vecColor[color1][1] * 13 + i] > 0 && m_byPokerPai[vecColor[color1][2] * 13 + i] > 0)
					{
						
						if(cbSrcCardType == Constants.CT_BAO_ZI)
						{
							if(m_byPokerPai[vecColor[color1][0] * 13 + i] > minCard)
							{
								out_cbCardData[0] = m_byPokerPai[vecColor[color1][0] * 13 + i];
								out_cbCardData[1] = m_byPokerPai[vecColor[color1][1] * 13 + i];
								out_cbCardData[2] = m_byPokerPai[vecColor[color1][2] * 13 + i];
								m_byPokerPai[vecColor[color1][0] * 13 + i] = 0;
								m_byPokerPai[vecColor[color1][1] * 13 + i] = 0;
								m_byPokerPai[vecColor[color1][2] * 13 + i] = 0;
								return;
							}
						}
						if(cbSrcCardType == Constants.CT_SHUN_JIN)
						{
							out_cbCardData[0] = m_byPokerPai[vecColor[color1][0] * 13 + i];
							out_cbCardData[1] = m_byPokerPai[vecColor[color1][1] * 13 + i];
							out_cbCardData[2] = m_byPokerPai[vecColor[color1][2] * 13 + i];
							m_byPokerPai[vecColor[color1][0] * 13 + i] = 0;
							m_byPokerPai[vecColor[color1][1] * 13 + i] = 0;
							m_byPokerPai[vecColor[color1][2] * 13 + i] = 0;
							return;
						}
					}
				}
			}

		}	
		if(cbSrcCardType == Constants.CT_SPECIAL)
		{
		}
		//printf("[%d]%02X,%02X,%02X\n",cbCardType,out_cbCardData[0],out_cbCardData[1],out_cbCardData[2]);
	}
	void RandCardList(int cbCardBuffer[], int cbBufferCount)
	{
		//memcpy(cbCardBuffer,m_cbCardListData,cbBufferCount);

		//混乱准备	
		System.arraycopy(m_cbCardListData, 0, m_byPokerPai, 0, 52);
	    
		/*
		int randseed1 = 0;
		int randseed2 = 0;
		for (int i = 0;i < 2000;i++)
		{
			randseed1 += randseed2;
			randseed2 = random(1,10000);
			int randPos1 = randseed1 % 52;
			int randPos2 = randseed2 % 52;

			int by1,by2;
			by1= m_byPokerPai[randPos1];
			by2= m_byPokerPai[randPos2];
			m_byPokerPai[randPos1] = by2;
			m_byPokerPai[randPos2] = by1;
		}
		
		//混乱扑克
		/*
		int bRandCount = 0, bPosition = 0;
		do
		{
			bPosition = (int) (random(1,10000) % (52 - m_byFetchPos));
			cbCardBuffer[m_byFetchPos++] = m_byPokerPai[bPosition];
			m_byPokerPai[bPosition] = m_byPokerPai[52 - m_byFetchPos];
		} while (m_byFetchPos < cbBufferCount);
		*/
		for(int i =0 ;i<cbBufferCount;i++)
		{
			int rand_Position = random(i*52,10000+i*52) % 52;
			for(int j=0;j<52;j++)
			{
				rand_Position = (rand_Position + j) % 52;
				if(m_byPokerPai[rand_Position] > 0)
				{
					cbCardBuffer[i] = m_byPokerPai[rand_Position];
					m_byPokerPai[rand_Position] = 0;
					break;
				}
			}

		}
		return;
	}

	//逻辑数值
	int GetCardLogicValue(int cbCardData)
	{
		//扑克属性
		int bCardColor = GetCardColor(cbCardData);
		int bCardValue = GetCardValue(cbCardData);

		//转换数值
		return (int) ((bCardValue == 1) ? (bCardValue + 13) : bCardValue);
	}
	public String GetCardStringType(int cbNextData[], int cbCardCount){
		int[] NextData= {0,0,0};
		System.arraycopy(cbNextData, 0, NextData, 0, 3);
		SortCardList(NextData, cbCardCount);
		int cbNextType = GetCardType(NextData, cbCardCount);
		switch(cbNextType){
			case 6:
				return "豹子";
			case 4:
				return "金花";
			case 3:
				return "顺子";
			case 5:
				return "顺金";
				
			case 2:
				return "对子";
		}
		return "";
	}
	//对比扑克
	public int CompareCard(int cbFirstData[], int cbNextData[], int cbCardCount)
	{
		//设置变量
		int[] FirstData = {0,0,0};int[] NextData= {0,0,0};
		System.arraycopy(cbFirstData, 0, FirstData, 0, 3);
		System.arraycopy(cbNextData, 0, NextData, 0, 3);

		//大小排序
		SortCardList(FirstData, cbCardCount);
		SortCardList(NextData, cbCardCount);

		//获取类型
		int cbNextType = GetCardType(NextData, cbCardCount);
		int cbFirstType = GetCardType(FirstData, cbCardCount);

		//特殊情况分析
		if ((cbNextType + cbFirstType) == (Constants.CT_SPECIAL + Constants.CT_BAO_ZI))return (cbFirstType > cbNextType ? 1 : 0);

		//还原单牌类型
		if (cbNextType == Constants.CT_SPECIAL)cbNextType = Constants.CT_SINGLE;
		if (cbFirstType == Constants.CT_SPECIAL)cbFirstType = Constants.CT_SINGLE;

		//类型判断
		if (cbFirstType != cbNextType) return (cbFirstType > cbNextType) ? 1 : 0;

		//简单类型
		switch (cbFirstType)
		{
		case 6://CT_BAO_ZI:			//豹子
		case 1://CT_SINGLE:			//单牌
		case 4://CT_JIN_HUA:		//金花
			{
				//对比数值
				for (int i = 0; i < cbCardCount; i++)
				{
					int cbNextValue = GetCardLogicValue(NextData[i]);
					int cbFirstValue = GetCardLogicValue(FirstData[i]);
					if (cbFirstValue != cbNextValue) return (cbFirstValue > cbNextValue) ? 1 : 0;
				}
				return 0;
			}
		case 3://CT_SHUN_ZI:		//顺子
		case 5://CT_SHUN_JIN:		//顺金 432>A32
			{		
				int cbNextValue = GetCardLogicValue(NextData[0]);
				int cbFirstValue = GetCardLogicValue(FirstData[0]);

				//特殊A32
				if (cbNextValue == 14 && GetCardLogicValue(NextData[cbCardCount - 1]) == 2)
				{
					cbNextValue = 3;
				}
				if (cbFirstValue == 14 && GetCardLogicValue(FirstData[cbCardCount - 1]) == 2)
				{
					cbFirstValue = 3;
				}

				//对比数值
				if (cbFirstValue != cbNextValue) return (cbFirstValue > cbNextValue) ? 1 : 0;
				;
				return DRAW;
			}
		case 2://CT_DOUBLE:			//对子
			{
				int cbNextValue = GetCardLogicValue(NextData[0]);
				int cbFirstValue = GetCardLogicValue(FirstData[0]);

				//查找对子/单牌
				int bNextDouble = 0, bNextSingle = 0;
				int bFirstDouble = 0, bFirstSingle = 0;
				if (cbNextValue == GetCardLogicValue(NextData[1]))
				{
					bNextDouble = cbNextValue;
					bNextSingle = GetCardLogicValue(NextData[cbCardCount - 1]);
				}
				else
				{
					bNextDouble = GetCardLogicValue(NextData[cbCardCount - 1]);
					bNextSingle = cbNextValue;
				}
				if (cbFirstValue == GetCardLogicValue(FirstData[1]))
				{
					bFirstDouble = cbFirstValue;
					bFirstSingle = GetCardLogicValue(FirstData[cbCardCount - 1]);
				}
				else 
				{
					bFirstDouble = GetCardLogicValue(FirstData[cbCardCount - 1]);
					bFirstSingle = cbFirstValue;
				}

				if (bNextDouble != bFirstDouble)return (bFirstDouble > bNextDouble) ? 1 : 0;
				if (bNextSingle != bFirstSingle)return (bFirstSingle > bNextSingle) ? 1 : 0;
				return DRAW;
			}
		}

		return DRAW;
	}
}
